'''
Created on Dec 8, 2010

@author: mkiyer
'''
import tempfile
import subprocess
import os
import logging
import argparse

def sam2bam(input_sam_file, output_bam_file, order_by='pos', samtools_path=None):    
    '''
    converts SAM format to BAM format, where reads are sorted
    by position and indexed
    '''
    samtools_bin = 'samtools'
    if samtools_path is not None:
        samtools_bin = os.path.join(samtools_path, samtools_bin)
    try:
        # make a temporary file to retain the unsorted BAM
        output_dir = os.path.dirname(output_bam_file)
        fh, tmp_bam_file = tempfile.mkstemp(suffix='bam', prefix='tmp', dir=output_dir)
        os.close(fh)
        args = [samtools_bin, 'view', '-bS', input_sam_file, '-o', tmp_bam_file]    
        retcode = subprocess.call(args)
        if retcode != 0:
            raise OSError("command: '%s' returned error code %s" % (' '.join(args), retcode))
        # sort BAM
        output_bam_prefix = os.path.splitext(output_bam_file)[0]
        args = [samtools_bin, 'sort']
        if order_by == 'name':
            args.append('-n')
        args.extend([tmp_bam_file, output_bam_prefix])
        retcode = subprocess.call(args)
        if retcode != 0:
            raise OSError("command: '%s' returned error code %s" % (' '.join(args), retcode))
        # index BAM
        args = [samtools_bin, 'index', output_bam_file]
        retcode = subprocess.call(args)
        if retcode != 0:
            raise OSError("command: '%s' returned error code %s" % (' '.join(args), retcode))
    finally:        
        os.remove(tmp_bam_file)
    return retcode

def main():
    logging.basicConfig(level=logging.DEBUG,
                        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    parser = argparse.ArgumentParser()
    parser.add_argument("--order", dest="order_by", default="pos")
    parser.add_argument("--samtools-path", dest="samtools_path", default=None)
    parser.add_argument("sam")
    parser.add_argument("bam")
    options = parser.parse_args()
    return sam2bam(options.sam, options.bam, options.order_by, options.samtools_path)

if __name__ == '__main__': 
    import sys
    sys.exit(main())